import { ValidateErrorInfo } from '@/ts/base/model';
import WorkFormService from '@/ts/scripting/core/services/WorkFormService';
import { Button, Popover, Tag } from 'antd';
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import {
  isRequiredValidateError,
  isRuleValidateError,
} from '@/ts/scripting/core/rule/ValidateHandler';
import cls from './index.module.less';
import { AiOutlineEdit } from 'react-icons/ai';
import { XValidation } from '@/ts/base/schema';
import { ValidationModal } from './ValidationModal';
import { ValidateMessageTable } from './ValidateMessageTable';

interface IProps {
  service: WorkFormService;
  onErrorClick?: (error: ValidateErrorInfo) => void;
}

const ReportValidateMessage: React.FC<IProps> = (props) => {
  const [validateVisible, setValidateVisible] = useState(false);
  const [validateErrors, setValidateErrors] = useState<ValidateErrorInfo[]>([]);

  const needFillValidation = useMemo(() => {
    return validateErrors.filter((e) => e.errorLevel != 'error').length > 0;
  }, [validateErrors]);

  const [validations, setValidation] = useState<XValidation[]>([]);
  const [fillVisible, setFillVisible] = useState(false);

  useEffect(() => {
    const dispose = props.service.onScoped('afterValidate', (args) => {
      setValidateErrors([...args]);
      const errors = args.filter((e) => e.errorLevel == 'error');
      const list = props.service.validate.validationInfo;
      const noReason = list.filter((e) => e.errorLevel != 'error' && !e.reason);
      if (errors.length > 0 || noReason.length > 0) {
        setValidateVisible(true);
      } else {
        setValidateVisible(false);
      }
    });
    const id = props.service.command.subscribe((type, cmd, args) => {
      if (type == 'validate') {
        if (cmd == 'show') {
          setValidateVisible(true);
        } else if (cmd == 'hide') {
          setValidateVisible(false);
        }
      }
    });
    return () => {
      dispose();
      props.service.command.unsubscribe(id);
    };
  }, []);

  function fillValidation() {
    const list = props.service.validate.validationInfo;
    setValidation(list);
    setValidateVisible(false);
    setFillVisible(true);
  }

  function renderPosition(error: ValidateErrorInfo) {
    let ret: ReactNode = error.position;

    let formName = <></>;
    let formId = (error as any).formId;

    if ((error as any).sheet) {
      formName = (
        <Tag color="processing" style={{ marginLeft: '8px' }}>
          {props.service.formInfo[(error as any).sheet]?.form.name ?? (error as any).sheet}
        </Tag>
      );
    } else if (formId) {
      formName = (
        <Tag color="processing" style={{ marginLeft: '8px' }}>
          {props.service.formInfo[formId]?.form.name ?? formId}
        </Tag>
      );
    }

    if (isRequiredValidateError(error)) {
      const name = 'cell' in error.field 
        ? ('单元格 ' + error.field.cell) 
        : error.field.name;
      return (
        <>
          <span>{name}</span>
          {formName}
        </>
      );
    } else if (isRuleValidateError(error)) {
      if (error.sheet) {
        return (
          <>
            <span>{error.position}</span>
            {formName}
          </>
        );
      }
      return (
        <>
          <span>规则：{error.rule.name}</span>
          {formName}
        </>
      );
    }
    return ret;
  }

  const content = () => {
    return (
      <ValidateMessageTable
        validateErrors={validateErrors}
        onErrorClick={props.onErrorClick}
        renderPosition={renderPosition}
        style={{ paddingTop: '0', width: '75vw' }}>
        <>
          {needFillValidation && (
            <div className={cls['edit-toolbar']}>
              <Button size="middle" type="primary" onClick={fillValidation}>
                <AiOutlineEdit style={{ marginRight: '8px' }} /> 填写说明
              </Button>
            </div>
          )}
          {fillVisible && (
            <ValidationModal
              data={validations}
              onCancel={() => setFillVisible(false)}
              allowEdit
              onFinish={async (data) => {
                setValidation(data);
                props.service.validate.validationInfo = data;
                return true;
              }}
            />
          )}
        </>
      </ValidateMessageTable>
    );
  };

  return (
    <Popover
      placement="top"
      content={content}
      trigger="click"
      open={validateVisible}
      onOpenChange={(v) => setValidateVisible(v)}>
      <div></div>
    </Popover>
  );
};

export default ReportValidateMessage;
